#ifndef SPRITE_H
#define SPRITE_H

#include <string>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <stdexcept>

#include "Image.h"

#include "Point2.h"
#include "Shape.h"

namespace gaim{
          
    class SpritePointerComparator;

    //Abstract Sprite class
    class Sprite{
    private:
        std::map<std::string, Image> images_;
        std::string image_;

        Point2 position_;
        Shape* shape_;

        int z_;
        
        bool isRect_;

        Sprite(const Sprite& other);
        Sprite& operator=(const Sprite& other);
    protected:
        Sprite(const std::map<std::string, Image>& images,
               const std::string& startingImage, const Point2& pos,
               const int& z, bool isRect);
    public:
        virtual ~Sprite();
        
        bool operator<(const Sprite* s);
        
        friend std::ostream& operator<<(std::ostream& os, Sprite& s);

        virtual void update(const std::set<Sprite*, SpritePointerComparator>& sprites, const double dt);
        virtual const std::set<Sprite*> checkCollisions(const std::set<Sprite*, SpritePointerComparator> sprites);

        virtual void draw(SDL_Surface * screen);
        
        const std::map<std::string, Image>& getImages() const;

        const std::string& getImage() const;
        void setImage(const std::string& image);

        void place(const double x, const double y);
        void place(const Point2& pos);

        const Point2& getPos() const;
        const Shape* getShape() const;

        const int& getZ() const;
        void setZ(const int z);

        SDL_Rect * getSDL_Rect() const;
        
        virtual void onCollision();
    };

    std::ostream& operator<<(std::ostream& os, Sprite& s);
    
    class SpritePointerComparator{
    public:
       bool operator()(const Sprite* s1, const Sprite* s2) const;
    };

}

#endif
